Менеджер проекта (Project Manager)
Окно Project Manager позволяет управлять проектом: добавлять и редактировать исходные коды проекта, изучить краткое ревью по утилизации ресурсов ПЛИС, используемых для реализации проекта, просматривать логи и сообщения о результатах сборки проекта и многое другое.
В первую очередь нас интересует окно исходных кодов проекта, которое называется Design Sources
и представлено на рис. 1.
Окно Design Sources
Данное окно находится по умолчанию в верхнем левом углу окна Project Manager (в случае, если вы случайно закрыли это окно, вы можете вернуть его обратно через меню Windows->Sources
).
Рисунок 1. Окно исходных кодов проекта.
Данное окно разделено на три вкладки:
- Иерархия (Hierarchy)
- Библиотеки (Libraries)
- Порядок сборки (Compile Order)
В определенных ситуациях в данном окне может появиться и вкладка IP Cores, но в рамках данного курса она нас не интересует.
Рассмотрим по порядку данные вкладки.
Вкладка Hierarchy
Данная вкладка состоит из четырех "папок":
- Design Sources;
- Constraints;
- Simulation Sources;
- Utility Sources.
В рамках текущего курса лабораторных работ мы будем взаимодействовать только с первыми тремя из них.
Помните, что несмотря на использование слова "папка", речь идет не о директориях операционной системы. Папки проекта — это всего лишь удобная абстракция для управления иерархией проекта.
В папке Design Sources
строится иерархия проектируемых модулей (исходников цифровых схем, которые в будущем могут быть воспроизведены в ПЛИС или заказной микросхеме).
Папка Constraints
содержит файлы ограничений, помогающих реализовать проект на конкретной ПЛИС (см. "Этапы реализации проекта в ПЛИС").
Simulation Sources
хранит в себе иерархию верификационного окружения, включая модули из папки Design Sources
— т.е. все модули (как синтезируемые, так и не синтезируемые), которые будут использованы при моделировании.
Обратите внимание на то, вкладка
Hierarchy
не содержит файлов. Здесь отображается иерархия модулей проекта. Один модуль может быть использован несколько раз — и в этом случае он будет столько же раз отображён в иерархии, хотя файл, хранящий описание этого модуля останется один (см. рис. 6).
Добавление файла в проект
Для того, чтобы добавить в проект новый файл, необходимо нажать на значок +
, расположенный в верхней части окна Sources
(либо использовать комбинацию горячих клавиш Alt+A
).
Появится окно добавления исходников. На первой странице этого окна будет необходимо выбрать тип добавляемого файла (см. рис. 2).
- файлы ограничений для синтеза схемы под конкретную ПЛИС (
Constraints
); - файлы проектируемой схемы (
Design Sources
); - файлы верификационного окружения для верификации схемы (
Simulation Sources
).
Рисунок 2. Первая страница окна добавления исходников.
В первую очередь мы хотим описать какую-нибудь простую схему, поэтому необходимо убедиться, что активным выбран пункт Design Sources
. Выбрав, нажимаем Next
.
Появится страница, представленная на рис. 3, которая предлагает три варианта добавления исходников.
- добавить существующий файл;
- добавить все имеющиеся файлы в заданной директории;
- создать новый файл.
Рисунок 3. Вторая страница окна добавления исходников.
Создадим новый файл, нажав на соответствующую кнопку окна. Появится всплывающее окно, предлагающее выбрать тип файла и его имя (см. рис. 4). В поле File Type
выберите SystemVerilog
(этот тип будет использоваться в качестве основного на протяжении всего курса кроме случаев, когда будет сказано иное). В поле File Name
задайте имя новому файлу (в рамках примера, имя файла будет max_min
). Указывать расширение файла не нужно — САПР автоматически его добавит в зависимости от выбранного типа файла. Когда всё будет готово, нажмите на OK
. После того, как были добавлены (или созданы) все необходимые источники, можно нажать кнопку Finish
в окне Add Sources
.
Рисунок 4. Окно создания нового файла.
В случае, если создавался новый файл, после нажатия на кнопку Finish
появится окно, предлагающее автоматически создать прототип модуля, указав в графическом интерфейсе направление и разрядность его портов (см. рис. 5). В рамках данного примера, откажемся от данного предложения, нажав кнопки Cancel->Yes
.
Рисунок 5. Окно описания входов и выходов модуля.
После добавления файлов с исходными кодами, Vivado автоматически начнет обновлять иерархию проекта. Вы можете заметить это по появившейся надписи Updating
с анимацией крутящейся стрелки, показанной на рис. 6.
Рисунок 6. Уведомление об обновлении иерархии проекта.
Пока в окне есть данное уведомление, не рекомендуется запускать подпрограммы во Flow Navigator
(к примеру, пытаться открыть схематик, запустить симуляцию/синтез и т.п.), поскольку иерархия проекта еще не построена и в конечном итоге может либо произойти ошибка, либо будет выполнено действие не для нужного вам модуля.
В зависимости от того, какие подпрограммы запущены через
Flow Navigator
, в момент вызова окнаAdd Sources
, Vivado автоматически будет стараться выбрать наиболее подходящий пункт (что не всегда будет совпадать с вашим намереньем). К примеру, вы описали модуль, запустили симуляцию, чтобы его проверить, а затем решили описать следующий модуль. Из-за того, что в момент вызова окнаAdd Sources
в фоне запущена симуляция, в этом окне по умолчанию будет выбран пунктSimulation Sources
.
После того, как Vivado закончит обновлять иерархию (и, если при создании файла вы отказались указывать порты модуля, нажав на кнопку Cancel
), рядом с папкой Design Sources
появится стрелка, позволяющая развернуть эту папку, внутри которой обнаружится подпапка Non-module Files
с созданным нами файлом. Новый файл пометили таким образом, поскольку он не содержит модуля. Как только в нем окажется описание какого-нибудь модуля, эта подпапка пропадёт.
Откроем редактор двойным кликом по файлу max_min.sv
и опишем в нём код, приведённый в листинге 1. В коде листингов 1-3 могут содержаться логические ошибки — они запланированы и будут найдены и исправлены в главе "Руководство по поиску и исправлению ошибок".
module max_min(
input logic [31:0] a,
input logic [31:0] b,
output logic [31:0] max,
output logic [ 3:0] min
);
always_comb begin
if(a > b) begin
max = a;
min = b;
end
else begin
max = b;
min = b;
end
end
endmodule
Листинг 1. Описание модуля max_min.
Не забудьте сохранить файл после описания в нем модуля нажав в редакторе на значок дискеты, или комбинацию клавиш Ctrl+S
.
Аналогичным образом, добавьте в Design Sources
проекта файлы half_divider
и vector_abs
и опишите в них модули, представленные в листингах 2-3 соответственно (все файлы листингов находятся в репозитории в папке Vivado Basics/vector_abs). На второй странице окна добавления исходников, представленном на рис. 3, вы можете создавать сразу несколько новых файлов. При создании убедитесь, что вы выбрали корректный тип файла.
module half_divider(
input logic [31:0] numerator,
output logic [31:0] quotient
);
assign quotient = numerator << 1'b1;
endmodule
Листинг 2. Описание модуля half_divider.
module vector_abs(
input logic [31:0] x,
input logic [31:0] y,
output logic [31:0] abs
);
logic [31:0] min;
logic [31:0] min_half;
max_min max_min_unit(
.a(x),
.b(y),
.max(max),
.min(min)
);
half_divider div_unit(
.numerator(min),
.quotient(min_half)
);
assign abs = max + min_half;
endmodule
Листинг 3. Описание модуля vector_abs.
В Simulation Sources
добавьте файл tb_vector_abs, описываемый листингом 4.
module tb_vector_abs();
logic [31:0] a;
logic [31:0] b;
logic [31:0] res;
vector_abs dut(
.x(a),
.y(b),
.abs(res)
);
integer err_count = 0;
task check_result(input logic [31:0]a, b, res);
begin : check_result
reg [31:0] ref_res;
ref_res = a < b? a/2 + b : a + b/2;
if (res !== ref_res) begin
$display("Incorrect res at time %0t:", $time);
$display("a = %0d, b = %0d", a, b);
$display("design res = %0d", res);
$display("reference res = %0d", ref_res);
$display("------------------");
err_count = err_count + 1'b1;
end
end
endtask
initial begin : test
integer i;
$timeformat(-9,0,"ns");
a = 0; b = 0;
#5;
check_result(a,b,res);
a = 1; b = 1;
#5;
check_result(a,b,res);
a = 3; b = 4;
#5;
check_result(a,b,res);
for(i = 0; i < 100; i=i+1) begin
a = $random()&32'hff; b = $random()&32'hff;
#5;
check_result(a,b,res);
end
$display("Test has been finished with %d errors", err_count);
if(err_count == 0) begin
$display("SUCCESS!");
end
$finish();
end
endmodule
Листинг 4. Описание модуля tb_vector_abs.
Построение иерархии модулей
После создания указанных файлов и описания в них модулей из листингов 2-4, иерархия модулей примет следующий вид, представленный на рис. 7.
Рисунок 7. Иерархия проекта, представленная в свёрнутом виде.
Нажав на стрелку слева от модуля vector_abs
, иерархия развернётся (рис. 8).
Рисунок 8. Иерархия проекта, представленная в развёрнутом виде.
Обратите внимание на то, что модуль vector_abs
выделен жирным относительно других модулей. Такое выделение означает, что данный модуль выбран в качестве модуля верхнего уровня (top-level module). Это означает, это данный модуль и представляет итоговую схему, которую мы проектируем, и что другие подпрограммы во Flow Navigator
, такие как RTL ANALYSIS
, SYNTHESIS
, IMPLEMENTATION
и PROGRAM AND DEBUG
будут обрабатывать именно этот модуль. Если вдруг вы захотите работать с другим модулем (например, с модулем, half_divider
) — его необходимо пометить вручную в качестве модуля верхнего уровня. Для этого необходимо нажать по нему правой кнопкой мыши, и в выпадающем меню выбрать Set as Top
(см. рис. 9).
Рисунок 9. Выбор модуля верхнего уровня (показана середина выпадающего списка).
Обратите внимание, как строится иерархия проекта. Модули, являющиеся объектами других модулей "вложены" в эти модули. Причем в иерархии проекта сперва указывается имя объекта модуля, затем через двоеточие имя самого модуля. В скобках указывается имя файла, где модуль описан. Модуль, который не содержится в других модулях не имеет имени объекта модуля (т.к. нет сущности, которая бы этот объект создавала). Если модуль будет содержать несколько объектов одного и того же модуля, в иерархии будут отображены все эти объекты — именно поэтому нужно понимать, чем иерархия модулей отличается от дерева файлов. Несмотря на то, что модуль описан всего в одном файле, в иерархии проекта может встречаться несколько экземпляров одного и того же модуля.
Добавьте в Simulation Sources
файл tb_vector_abs
, содержимое которого представлено в листинге 4.
module tb_vector_abs();
logic [31:0] a;
logic [31:0] b;
logic [31:0] res;
vector_abs dut(
.x(a),
.y(b),
.abs(res)
);
integer err_count = 0;
task check_result(input logic [31:0]a, b, res);
begin : check_result
reg [31:0] ref_res;
ref_res = a < b? a/2 + b : a + b/2;
if (res !== ref_res) begin
$display("Incorrect res at time %0t:", $time);
$display("a = %0d, b = %0d", a, b);
$display("design res = %0d", res);
$display("reference res = %0d", ref_res);
$display("------------------");
err_count = err_count + 1'b1;
end
end
endtask
initial begin : test
integer i;
$timeformat(-9,0,"ns");
a = 0; b = 0;
#5;
check_result(a,b,res);
a = 1; b = 1;
#5;
check_result(a,b,res);
a = 3; b = 4;
#5;
check_result(a,b,res);
for(i = 0; i < 100; i=i+1) begin
a = $random()&32'hff; b = $random()&32'hff;
#5;
check_result(a,b,res);
end
$display("Test has been finished with %d errors", err_count);
if(err_count == 0) begin
$display("SUCCESS!");
end
$finish();
end
endmodule
Листинг 4. Описание модуля tb_vector_abs.
Ошибки иерархии
В случае, если при создании какого-либо из файлов вы ошиблись с папкой назначения (добавили файл, предназначенный для Design Sources
в Simulation Sources
или наоборот), вы можете перенести этот файл в нужную папку без необходимости его удаления и повторного добавления. Для этого кликните по нужному файлу правой кнопкой мыши и выберите Move to Design/Simulation sources
(см. рис. 10).
Рисунок 10. Перенос модуля в нужную папку.
После добавления модуля tb_vector_abs
, обратите внимание на иерархию Simulation Sources
. Обратите внимание на то, что все модули Design Sources
продублированы в Simulation Sources
. Это ещё одно отличие от дерева файлов. Физически каждый модуль находится всего в одном файле, здесь представлена иерархия модулей.
Можно также заметить, что модуль верхнего уровня в Simulation Sources
другой. Модуль верхнего уровня в Simulation Sources
определяет то, какой модуль будет использоваться при симуляции (обычно это тестбенч, внутри которого создан объект проверяемого модуля). Модули верхнего уровня в Design Sources
и Simulation Sources
не связаны друг с другом (вам не нужно выбирать модулем верхнего уровня в Design Sources
тот модуль, что вы будете проверять с помощью тестбенча в Simulation Sources
).
Давайте изменим в модуле tb_vector_abs
название модуля vector_abs
, использовавшееся при создании объекта DUT
(например на vector
). Получившаяся иерархия модулей представлена на рис. 11.
Рисунок 11. Иерархия проекта с отсутствующим модулем.
Иерархия обновилась, но поскольку в проекте не существует модуля с названием vector
, это отобразилось соответствующим образом. Поскольку модуль vector_abs
не является частью модуля tb_vector_abs
, он перестал быть вложенным модулем и разместился рядом в Simulation Sources
(в Design Sources
иерархия осталась прежде, т.к. изменения коснулись только модуля tb_vector_abs
, расположенного в Simulation Sources
).
Вкладка Libraries
В данной вкладке находятся файлы проекта, сгруппированные по библиотекам. В рамках данного курса, эта вкладка использоваться не будет.
Вкладка Compile Order
Обычно Vivado сам определяет порядок компиляции по иерархии проекта. Однако, в некоторых ситуациях он может определить что-то неправильно. На данной вкладке вы можете исправить порядок компиляции (скорее всего, вам может потребоваться эта вкладка, для указания порядка компиляции пакетов SystemVerilog).
Дополнительные материалы
Более подробную информацию по окну Sources
вы можете найти в руководстве пользователя Vivado: "Vivado Design Suite User Guide: Using the Vivado IDE (UG893)" (раздел "Using the Sources Window").